import { describe, expect, test } from "vitest";
import { customizeWorkerConfig } from "../plugin-config";
import type { ResolvedWorkerConfig } from "../plugin-config";

// Create a minimal mock config for testing
function createMockConfig(
	overrides: Partial<ResolvedWorkerConfig> = {}
): ResolvedWorkerConfig {
	return {
		name: "test-worker",
		topLevelName: "test-worker",
		compatibility_date: "2024-01-01",
		main: "./src/index.ts",
		compatibility_flags: [],
		limits: {},
		rules: [],
		...overrides,
	} as ResolvedWorkerConfig;
}

describe("customizeWorkerConfig", () => {
	test("should return the original config when config is undefined", () => {
		const config = createMockConfig();
		const result = customizeWorkerConfig(config, undefined);
		expect(result).toBe(config);
	});

	test("should merge object configuration into the config", () => {
		const config = createMockConfig({ compatibility_date: "2024-01-01" });
		const result = customizeWorkerConfig(config, {
			compatibility_date: "2025-01-01",
		});
		expect(result.compatibility_date).toBe("2025-01-01");
		expect(result.name).toBe("test-worker");
	});

	test("should merge function result into the config", () => {
		const config = createMockConfig();
		const result = customizeWorkerConfig(config, (cfg) => ({
			compatibility_date: "2025-06-01",
			name: `modified-${cfg.name}`,
		}));
		expect(result.compatibility_date).toBe("2025-06-01");
		expect(result.name).toBe("modified-test-worker");
	});

	test("should return original config when function returns undefined/void", () => {
		const config = createMockConfig();
		const result = customizeWorkerConfig(config, () => {
			// Function that returns void/undefined
		});
		expect(result).toBe(config);
	});

	test("should allow function to mutate config in place", () => {
		const config = createMockConfig({ compatibility_date: "2024-01-01" });
		const result = customizeWorkerConfig(config, (cfg) => {
			cfg.compatibility_date = "2025-06-01";
			// Return void to indicate in-place mutation
		});
		// The original config should be returned (same reference)
		expect(result).toBe(config);
		// And the mutation should be visible
		expect(result.compatibility_date).toBe("2025-06-01");
	});

	test("should merge compatibility_flags arrays using defu semantics", () => {
		const config = createMockConfig({
			compatibility_flags: ["a"],
		});
		const result = customizeWorkerConfig(config, {
			compatibility_flags: ["b"],
		});
		// defu merges arrays
		expect(result.compatibility_flags).toEqual(
			expect.arrayContaining(["a", "b"])
		);
	});

	test("should preserve existing config values not specified in customize", () => {
		const config = createMockConfig({
			name: "original-name",
			compatibility_date: "2024-01-01",
		});
		const result = customizeWorkerConfig(config, {
			compatibility_date: "2025-01-01",
		});
		expect(result.name).toBe("original-name");
		expect(result.compatibility_date).toBe("2025-01-01");
	});
});
